home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / METAKIT.ZIP / EXAMPLES / CATFISH / SETUPDLG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-09  |  8.7 KB  |  311 lines

  1. //  setupdlg.cpp  -  setup dialog sample code
  2. //
  3. //  This is a part of the MetaKit library.
  4. //  Copyright (c) 1996 Meta Four Software.
  5. //  All rights reserved.
  6. /////////////////////////////////////////////////////////////////////////////
  7.  
  8. #include "stdafx.h"
  9. #include "catfish.h"
  10. #include "setupdlg.h"
  11. #include "pickdir.h"
  12.  
  13. #ifdef _DEBUG
  14. #undef THIS_FILE
  15. static char BASED_CODE THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CSetupDialog dialog
  20.  
  21. CSetupDialog::CSetupDialog(CWnd* pParent /*=NULL*/)
  22.     : CDialog(CSetupDialog::IDD, pParent),
  23.       m_exists (FALSE), m_timer (0), m_allowScan (FALSE)
  24. {
  25.     //{{AFX_DATA_INIT(CSetupDialog)
  26.     m_name = "";
  27.     //}}AFX_DATA_INIT
  28. }
  29.  
  30. void CSetupDialog::DoDataExchange(CDataExchange* pDX)
  31. {
  32.     CDialog::DoDataExchange(pDX);
  33.     //{{AFX_DATA_MAP(CSetupDialog)
  34.     DDX_Control(pDX, IDOK, m_okBtn);
  35.     DDX_Control(pDX, IDC_BROWSE_BTN, m_browseBtn);
  36.     DDX_Control(pDX, IDC_DEL_BTN, m_deleteBtn);
  37.     DDX_Control(pDX, IDC_ADD_BTN, m_addBtn);
  38.     DDX_Control(pDX, IDC_UPDATE_BTN, m_updateBtn);
  39.     DDX_Control(pDX, IDC_STATUS, m_status);
  40.     DDX_Control(pDX, IDC_ROOT, m_root);
  41.     DDX_Text(pDX, IDC_NAME, m_name);
  42.     //}}AFX_DATA_MAP
  43. }
  44.  
  45. BEGIN_MESSAGE_MAP(CSetupDialog, CDialog)
  46.     //{{AFX_MSG_MAP(CSetupDialog)
  47.     ON_BN_CLICKED(IDC_ADD_BTN, OnAddBtn)
  48.     ON_BN_CLICKED(IDC_UPDATE_BTN, OnUpdateBtn)
  49.     ON_BN_CLICKED(IDC_DEL_BTN, OnDelBtn)
  50.     ON_BN_CLICKED(IDC_BROWSE_BTN, OnBrowseBtn)
  51.     ON_EN_CHANGE(IDC_NAME, OnChangeName)
  52.     ON_EN_CHANGE(IDC_ROOT, OnChangeRoot)
  53.     ON_WM_TIMER()
  54.     ON_EN_KILLFOCUS(IDC_ROOT, OnKillfocusRoot)
  55.     //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57.  
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CSetupDialog message handlers
  60.  
  61.     // this member is called by the ScanDisk code during its (lengthy) scan
  62. bool CSetupDialog::UpdateStatus(const char* text)
  63. {
  64.     static DWORD lastTick = 0;
  65.     
  66.         // a null pointer forces immediate clear of the status text
  67.     if (!text)
  68.     {
  69.         lastTick = 0;
  70.         text = "";
  71.     }
  72.     
  73.         // only refresh the status message every quarter second
  74.     if (GetTickCount() > lastTick + 250)
  75.     {
  76.         lastTick = GetTickCount();
  77.         m_status.SetWindowText(text);   
  78.     }
  79.     
  80.     return cStatusHandler::UpdateStatus(text) && m_allowScan;
  81. }
  82.  
  83.     // the name has changed, update other fields (either now, or a little later)
  84.     // this delay is used to avoid excessive activity while a name is typed in
  85. void CSetupDialog::NameChange(BOOL delay)
  86. {
  87.     CString s;
  88.     if (m_name.IsEmpty())
  89.         s = "(please enter name of catalog)";
  90.     m_status.SetWindowText(s);
  91.  
  92.     m_exists = FALSE;
  93.     
  94.     if (delay)
  95.     {       // arm the timer (if there is a catalog name)
  96.         KillTimer(m_timer);
  97.         m_timer = m_name.IsEmpty() ? 0 :
  98.                     SetTimer(1, 500, 0); // timeout in 500 mS
  99.     }
  100.     else
  101.         InspectCatalog();
  102. }
  103.  
  104.     // scan through the directories, but be prepared to deal with premature abort
  105. void CSetupDialog::ScanDirectories()
  106. {
  107.     CString s;
  108.     m_root.GetWindowText(s);
  109.     
  110.         // prepare for a lengthy scan with a cancel option
  111.     AdjustButtons(TRUE);                        
  112.                             
  113.     m_okBtn.EnableWindow(FALSE);
  114.     m_browseBtn.SetWindowText("Abort");
  115.     SetDefID(IDC_BROWSE_BTN);
  116.  
  117.     m_allowScan = TRUE;
  118.                             
  119.         // build a catalog of the specified directory tree
  120.     c4_View dirs = fScanDirectories(s, this);
  121.                             
  122.         // restore normal situation
  123.     m_allowScan = TRUE;
  124.     m_okBtn.EnableWindow(TRUE);
  125.     m_browseBtn.SetWindowText("Browse");
  126.                             
  127.     m_status.SetWindowText("Saving catalog...");
  128.         // saving may take a litle time
  129.     HCURSOR oldCursor = SetCursor(LoadCursor(0, IDC_WAIT));
  130.     
  131.     if (dirs.GetSize() > 0)
  132.     {                        
  133.         s = m_name + FILE_TYPE;
  134.                                 
  135.             // clumsy, remove file to create smallest file
  136.         CFileStatus fs;
  137.         if (CFile::GetStatus(s, fs))
  138.             CFile::Remove(s);
  139.                                 
  140.             // this stores the catalog on file  
  141.         c4_Storage storage (s, true);
  142.         storage.Store("dirs", dirs);
  143.         storage.Commit();
  144.     }
  145.                             
  146.     SetCursor(oldCursor);
  147.     
  148.     InspectCatalog();
  149. }     
  150.  
  151.     // go see if the catalog exists and get its file date and root path
  152. void CSetupDialog::InspectCatalog()
  153. {
  154.     UpdateData();
  155.                             
  156.     CString s = GetCatalogDate(m_name);
  157.     if (!s.IsEmpty())
  158.         s = "Last change:  " + s;
  159.  
  160.     UpdateData(FALSE); // adjusts the name
  161.                                                             
  162.     m_status.SetWindowText(s);
  163.     m_exists = !s.IsEmpty();
  164.                                 
  165.     if (m_exists)
  166.     {
  167.             // load the root path name from the catalog
  168.             // this is quick, due to on-demand loading
  169.         c4_Storage storage (m_name + FILE_TYPE, false);
  170.         c4_View dirs = storage.View("dirs");
  171.         m_origRoot = pName (dirs[0]);
  172.         m_root.SetWindowText(m_origRoot);
  173.     }
  174. }
  175.  
  176.     // adjust the button dimming and titles to reflect the current situation
  177. void CSetupDialog::AdjustButtons(BOOL inScan_)
  178. {
  179.     CString s;
  180.     m_root.GetWindowText(s);
  181.     BOOL valid = !s.IsEmpty() && !inScan_;
  182.     
  183.         // don't enable buttons while the timer is running  
  184.     m_addBtn.EnableWindow(valid && !m_exists && !m_timer && !m_name.IsEmpty());
  185.     
  186.     ASSERT(!(m_exists && m_timer)); // if it exists, timer cannot be running
  187.     m_updateBtn.EnableWindow(valid && m_exists);
  188.     m_deleteBtn.EnableWindow(valid && m_exists);
  189.     
  190.         // The default button is "OK" for existing files
  191.         // If the root has been set for a new file, the default is "Add"
  192.         // For new files, or if the root is different, the default is "Browse"
  193.         // Never make "Change" the default, since that is a dangerous change
  194.     SetDefID(valid &&  m_exists && s == m_origRoot ? IDOK :
  195.              valid && !m_exists && !m_timer        ? IDC_ADD_BTN : 
  196.                                                      IDC_BROWSE_BTN);
  197.     
  198.     if (!GetFocus())
  199.         m_okBtn.SetFocus();
  200. }
  201.                             
  202.         // called shortly after a change to the name or root edit control       
  203. void CSetupDialog::OnTimer(UINT nIDEvent)
  204. {
  205.     KillTimer(m_timer);
  206.     m_timer = 0;
  207.     
  208.     InspectCatalog();
  209.     OnChangeRoot();
  210.     
  211.     CDialog::OnTimer(nIDEvent);
  212. }
  213.             
  214. BOOL CSetupDialog::OnInitDialog()
  215. {
  216.     CenterWindow();
  217.     CDialog::OnInitDialog();
  218.     
  219.     m_nameEditCtrl.SubclassDlgItem(IDC_NAME, this);
  220.     
  221.     NameChange(FALSE);
  222.     AdjustButtons();
  223.     
  224.     return TRUE;  // return TRUE  unless you set the focus to a control
  225. }
  226.  
  227. void CSetupDialog::OnAddBtn()
  228. {
  229.     OnKillfocusRoot();
  230.     ScanDirectories();
  231.     AdjustButtons();
  232. }
  233.  
  234. void CSetupDialog::OnUpdateBtn()
  235. {
  236.     OnKillfocusRoot();
  237.     ScanDirectories();
  238.     AdjustButtons();
  239. }
  240.  
  241. void CSetupDialog::OnDelBtn()
  242. {
  243.     if (AfxMessageBox("Do you want to permanently delete "
  244.                         "the catalog named '" + m_name + "' ?",
  245.                         MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2) == IDYES)
  246.     {
  247.         CFile::Remove(m_name + FILE_TYPE);
  248.  
  249.         NameChange(TRUE);
  250.         AdjustButtons();
  251.     }
  252. }
  253.  
  254. void CSetupDialog::OnBrowseBtn()
  255. {
  256.     if (m_allowScan)
  257.     {
  258.         m_allowScan = FALSE;
  259.         return;
  260.     }
  261.     
  262.     CString dir = PickDirectory(this);
  263.     if (!dir.IsEmpty())
  264.         m_root.SetWindowText(dir); // triggers OnChangeRoot()
  265. }
  266.  
  267. void CSetupDialog::OnChangeName()
  268. {
  269.     VERIFY(UpdateData());
  270.  
  271.     NameChange(TRUE);
  272.     AdjustButtons();
  273. }
  274.  
  275. void CSetupDialog::OnChangeRoot()
  276. {
  277.     CString s;
  278.     m_root.GetWindowText(s);
  279.                             
  280.     BOOL changed = m_exists && s != m_origRoot;
  281.     m_updateBtn.SetWindowText(changed ? "&Change" : "&Update");
  282.     
  283.     AdjustButtons();
  284. }
  285.  
  286. void CSetupDialog::OnKillfocusRoot()
  287. {
  288.     CString s;
  289.     m_root.GetWindowText(s);
  290.     
  291.     if (!s.IsEmpty())
  292.     {
  293.         s.MakeUpper();
  294.         if (s.Right(1) != "\\")
  295.             s += "\\"; // avoid handing "C:" to _fullpath
  296.  
  297.         char buf [_MAX_PATH];
  298.         if (_fullpath(buf, s + "nul", sizeof buf))
  299.         {
  300.             s = buf;
  301.         
  302.             CFileStatus fs;
  303.             if (CFile::GetStatus(s, fs))
  304.                 m_root.SetWindowText(s.Left(s.GetLength() - 4));
  305.         }
  306.     }
  307. }
  308.  
  309. /////////////////////////////////////////////////////////////////////////////
  310. // $Id: setupdlg.cpp,v 1.2 1996/12/04 14:49:37 jcw Exp $
  311.